# encoding:utf-8
'''
@author : xaing
@time : 2018/4/18 20:33
@地址 : 广州
@作用 : 下载笔趣阁小说
  只需要设置下 小说的主目录和文件保存位置就可以下载小说
@结果 :
'''

import urllib.request
import re
import os
import time
import socket

'''
要爬取的小说主目录
'''
baseUrl = 'https://www.biqiuge.com/book/14184/'
# 笔趣阁基础目录
base = "https:/www.biqiuge.ccm"
# 文件保存位置
downPath = "E:\\下载\\book"


def getHtml(url):
    '''
    获取网页
    :param url: 网页地址
    :return: 返回网页源码
    '''
    try:
        # # 带上参数，让他更像浏览器
        headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'}
        # 超时设置
        timeout = 200
        socket.setdefaulttimeout(timeout)
        req = urllib.request.Request(url=url, headers=headers)

        html = urllib.request.urlopen(req).read().decode('gbk')
        # print("网页源码：" + html)
        return html
    except (Exception, TimeoutError) as e:
        print(e)
        print("没有返回数据，等待10秒后继续请求")
        # time.sleep(3)
        getHtml(url)


def getBookName(html):
    '''
    返回小说的名字,或章节名字
    :param html:
    :return:
    '''
    # p = r'h1>([^<]+)'
    p = r'<h1>([^<h1/>]+)'
    bookName = re.findall(p, str(html))
    return bookName

def getAllSon(html):
    '''
    获取全部子页面
    :param html:
    :return:
    '''
    p = r'<dd><a href=\"([^">]+)'
    sonAll = re.findall(p, str(html))
    return sonAll

def sonSplice(url):
    '''
    拼接形成地址
    :param url:
    :return:
    '''
    synthesisUrl = base + url
    return synthesisUrl

def getBookContent(htmlContent):
    '''
    返回小说的正文内容
    :param html:
    :return:
    '''
    # p = r'<div id="content">([^div>]+)'
    p = r'<div id="content">([\s\S]*?)</div>'  # ？启用非贪婪模式
    bookContent = re.findall(p, str(htmlContent))
    # 去除里面的<a>元素等
    bookContent[0] = bookContent[0].replace(' ', ' ')
    bookContent[0] = bookContent[0].replace('&nbsp;', '')
    bookContent[0] = bookContent[0].replace('<br />', '')
    content = re.sub(r'<a.*?>(.*?)</a>', '', bookContent[0])
    return content

# html = getHtml(baseUrl)
# son = getAllSon(html)
# for s in son:
#     ss = sonSplice(s)
#     print(ss)


def initDown():
    '''
    初始化下载工作
    :return:
    '''
    # 判断文件夹是否存在，否则创建
    if os.path.exists(downPath):
        print("下载目录已经存在···")
    else:
        os.makedirs(downPath)
        print("创建下载目录中·······")


def createTxt(name):
    '''
    创建小说.txt
    :param name:小说名
    :return: 返回小说路径
    '''
    # 查看当前路径
    os.getcwd()
    # 更改程序到指定路径下
    os.chdir(r"" + str(downPath) + "")
    # 文件名
    fileName = str(name[0]) + ".txt"
    course = open(fileName, 'w', encoding='utf8')
    # 释放资源
    course.close()
    print("创建小说成功,获得小说路径：" + str(downPath + fileName))
    return downPath + '\\' + fileName

def writeTxt(filePath, content):
    '''
    写小说到文件中
    :param fielPath: 文件地址
    :param content: 要写的文件
    :return:
    '''
    # a就是追加 w+写读（会覆盖之前的）  可以指定编码，也可以不指定
    # f = open(fielPath, 'a', encoding='utf-8')
    # f.write(content)
    # f.write("\n")  # 换行
    # f.close()
    with open(filePath, 'a') as f:
        f.write(content)
        f.write("\n")  # 换行

def mainDef():
    # 初始化文件夹
    initDown()
    baseHtml = getHtml(baseUrl)
    # 获取小说名
    bookName = getBookName(baseHtml)
    # 创建小说并得到路径
    bookPath = createTxt(bookName)
    # 写入小说名
    writeTxt(bookPath, bookName[0])
    # 计数器
    bookCounter = 1
    # 获取全部子页面
    allSon = getAllSon(baseHtml)
    for son in allSon:
        # 拼接地址
        sonurl = sonSplice(son)
        # 拿到子页面
        sonHtml = getHtml(sonurl)
        # 获得子页面标题
        sonTitle = getBookName(sonHtml)
        print(str(bookCounter) + "正在下载====" + str(sonTitle) + "章节")
        writeTxt(bookPath, sonTitle[0])
        # 小说正文获取
        content = getBookContent(sonHtml)
        writeTxt(bookPath, content)
        print("完成" + str(son) + "页面的下载")
        time.sleep(5)
        bookCounter = bookCounter + 1

mainDef()